package com.shelpe.services.sinbad.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.shelpe.services.sinbad.controller.dto.KeywordRealtimeRank;
import com.shelpe.services.sinbad.dto.BalanceRtrDto;
import com.shelpe.services.sinbad.model.Keyword;
import com.shelpe.services.sinbad.model.KeywordExample;
import com.shelpe.services.sinbad.readdao.KeywordMapper;
import com.shelpe.services.sinbad.service.rtr.BalanceService;
import com.shelpe.services.sinbad.service.rtr.CostService;
import com.shelpe.services.sinbad.service.rtr.RealRankingService;
import com.shelpe.services.sinbad.service.simbaproxy.AuthClient;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping(value = "/sinbadservice")
@Api("实时数据相关的API")
public class RealtimeReportController {
	@Autowired
	private BalanceService balanceService;
	@Autowired
	private CostService costService;
	@Autowired
	private RealRankingService realRankingService;
	@Autowired
	private KeywordMapper keywordMapper;
	@Autowired
	private AuthClient authClient;

	@ApiOperation("实时获取账户余额信息")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "user_id", value = "淘宝用户id", required = true, paramType = "path", dataType = "long"),
			@ApiImplicitParam(name = "time", value = "同步间隔时间,0：即时同步,单位：分钟", defaultValue = "0", required = false, paramType = "query", dataType = "int") })
	@RequestMapping(path = "/users/{user_id}/reports/@realtime_balance", method = RequestMethod.GET)
	public BalanceRtrDto getAccountBalance(@PathVariable("user_id") long userID,
			@RequestParam(name = "time", required = false, defaultValue = "0") int time) {
		BalanceRtrDto dto = new BalanceRtrDto();
		Date queryTime = DateUtils.addMinutes(new Date(), -time);

		BalanceRtrDto mongoPo = this.balanceService.findBalance(userID, queryTime, time);
		if (mongoPo != null && (mongoPo.getBalance() != null || mongoPo.getError() != null)) {
			if (mongoPo.getBalance() != null) {
				dto.setBalance(mongoPo.getBalance());
			}
			if (mongoPo.getError() != null) {
				dto.setError(mongoPo.getError());
			}
		} else {
			AuthClient.UserToken token = this.authClient.findSessionKeyByID(userID);
			if (token != null && token.isExpired()) {
				return dto;
			}
			BalanceRtrDto resDto = this.balanceService.syncBalance(userID, time);
			if (resDto != null) {
				if (resDto.getError() != null) {
					dto.setError(resDto.getError());
				} else {
					dto.setBalance(resDto.getBalance());
				}
			}
		}
		return dto;
	}

	@ApiOperation("获取账户实时报表数据")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "user_id", value = "淘宝用户id", required = true, paramType = "path", dataType = "long"),
			@ApiImplicitParam(name = "time", value = "同步间隔时间,0：即时同步,单位：分钟", defaultValue = "0", required = false, paramType = "query", dataType = "int") })
	@RequestMapping(path = "/users/{user_id}/reports/@realtime_cost", method = RequestMethod.GET)
	public com.shelpe.services.sinbad.dto.EffectMetricDto getRealtimeCost(@PathVariable("user_id") long userID,
			@RequestParam(name = "time", required = false, defaultValue = "0") int time) {
		com.shelpe.services.sinbad.dto.EffectMetricDto dto = new com.shelpe.services.sinbad.dto.EffectMetricDto();
		Date queryTime = DateUtils.addMinutes(new Date(), -time);

		com.shelpe.services.sinbad.dto.EffectMetricDto mongoPo = this.costService.findCost(userID, queryTime, time);
		if (mongoPo != null) {
			BeanUtils.copyProperties(mongoPo, dto);
		} else {
			AuthClient.UserToken token = this.authClient.findSessionKeyByID(userID);
			if (token != null && token.isExpired()) {
				return dto;
			}
			com.shelpe.services.sinbad.dto.EffectMetricDto resDto = this.costService.syncCost(userID, time);
			if (resDto != null) {
				BeanUtils.copyProperties(resDto, dto);
			}
		}
		return dto;
	}

	@ApiOperation("获取卡位实时报表数据")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "device", defaultValue = "all", allowableValues = "pc, mobile, all", paramType = "query", dataType = "string"),
			@ApiImplicitParam(name = "time", value = "同步间隔时间,0：即时同步,单位：分钟", defaultValue = "0", required = false, paramType = "query", dataType = "int") })
	@RequestMapping(path = "/v2/users/{user_id}/realtime_ranks", method = RequestMethod.GET)
	public List<KeywordRealtimeRank> getKeywordRealtimeRanks(@PathVariable("user_id") long userID,
			@RequestParam("keyword_ids") List<Long> keywordIDs,
			@RequestParam(name = "device", required = false, defaultValue = "all") String device,
			@RequestParam(name = "time", required = false, defaultValue = "0") int time) {
		Date queryTime = DateUtils.addMinutes(new Date(), -time);
		List<KeywordRealtimeRank> dtos = new ArrayList<KeywordRealtimeRank>();
		/** 查询关键词 **/
		KeywordExample ke = new KeywordExample();
		ke.setUserId(userID);
		ke.createCriteria().andKeywordIdIn(keywordIDs);
		List<Keyword> keywords = this.keywordMapper.selectByExample(ke);

		List<Long> needKeywordIDs = new ArrayList<Long>();
		for (Keyword kw : keywords) {
			if (needKeywordIDs.indexOf(kw.getKeywordId()) == -1) {
				needKeywordIDs.add(kw.getKeywordId());
			}
		}
		Map<Long, Keyword> map = new HashMap<Long, Keyword>();
		for (Keyword keyword : keywords) {
			map.put(keyword.getKeywordId(), keyword);
		}
		if (keywords != null && keywords.size() > 0) {
			dtos = this.realRankingService.findRanking(keywords, keywords.get(0).getAdgroupId(), keywordIDs, queryTime,
					device, time);
			if (dtos == null || dtos.size() == 0) {
				AuthClient.UserToken token = this.authClient.findSessionKeyByID(userID);
				if (token != null && token.isExpired()) {
					return dtos;
				}
				dtos = this.realRankingService.syncRanking(keywords, keywords.get(0).getAdgroupId(), keywordIDs, device,
						time);
			}
		}
		return dtos;
	}
}
